﻿@page "/Device/{Id:guid?}"
@page "/Device/{Action}/{Id:guid?}"
@using Gurux.DLMS.AMI.Client.Pages.Objects
@using Gurux.DLMS.AMI.Shared.DIs
@using Gurux.DLMS.AMI.Shared.DTOs.Manufacturer;
@using Gurux.DLMS.AMI.Shared.Rest;
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs.Authentication
@using Gurux.DLMS.AMI.Shared
@using Gurux.DLMS.AMI.Shared.Enums
@using Gurux.DLMS.AMI.Shared.DTOs
@using System.Diagnostics;

@attribute [Authorize(Roles = GXRoles.Admin + "," + GXRoles.DeviceManager + "," + GXRoles.DeviceGroupManager)]
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IGXNotifier Notifier

@if (!NotInitialized)
{
    <h1>
        @Title
    </h1>
    <CascadingValue Value="this">
        <TabControl Active="@Action">
            <TabTextTemplate>
                <span class=@context.Icon aria-hidden="true"></span>
                @context.Text
            </TabTextTemplate>
            <ChildContent>
                <AuthorizeView Roles=@GXRoles.ToString(GXRoles.Admin, GXRoles.DeviceManager)>
                    <TabPage Text=@Properties.Resources.GeneralInformation Icon="oi oi-timer">
                        <div style="position: relative; width: 100%; ">
                            <Device @ref="_device" Action="@Action"></Device>
                        </div>
                    </TabPage>
                </AuthorizeView>
                <AuthorizeView Roles=@GXRoles.ToString(GXRoles.Admin, GXRoles.UserGroupManager)>
                    <TabPage Text=@Properties.Resources.DeviceGroups Icon="oi oi-timer">
                        <div style="position: relative; width: 100%; ">
                            <DeviceGroupsSelector></DeviceGroupsSelector>
                        </div>
                    </TabPage>
                </AuthorizeView>
                <AuthorizeView Roles=@GXRoles.ToString(GXRoles.Admin, GXRoles.DeviceManager)>
                    <TabPage Text=@Properties.Resources.Objects Icon="oi oi-timer">
                        <div style="position: relative; width: 100%; ">
                            <Objects></Objects>
                        </div>
                    </TabPage>
                </AuthorizeView>
            </ChildContent>
        </TabControl>
    </CascadingValue>
}
<br />
@code {
    /// <summary>
    /// If manufacturers or device templates are not installed.
    /// </summary>
    bool NotInitialized;
    /// <summary>
    /// Action.
    /// </summary>
    [Parameter]
    public string? Action { get; set; }

    /// <summary>
    /// Device UI reference.
    /// </summary>
    private Device? _device;

    /// <summary>
    /// Active page.
    /// </summary>
    [Parameter]
    public string? Page { get; set; }

    /// <summary>
    /// Target ID.
    /// </summary>
    [Parameter]
    public Guid? Id { get; set; }

    /// <summary>
    /// Page title.
    /// </summary>
    private string? Title;

    /// <summary>
    /// Active item.
    /// </summary>
    public GXDevice Active = new GXDevice(null)
        {
            TraceLevel = TraceLevel.Off
        };

    /// <summary>
    /// List of manufacturer templates.
    /// </summary>
    public List<GXDeviceTemplate>? ManufacturerTemplates;
    /// <summary>
    /// List of custom templates.
    /// </summary>
    public List<GXDeviceTemplate>? CustomTemplates;
    /// <summary>
    /// Installed manufacturers.
    /// </summary>
    public GXManufacturer[]? Manufacturers;
    public GXDeviceTemplate[]? Templates;

    /// <summary>
    /// Separate custom templates the manufacturer templates.
    /// </summary>
    private void UpdateTemplates(IEnumerable<GXDeviceTemplate> templates)
    {
        Templates = templates.ToArray();
        //Get Manufacturer templates.
        List<Guid> manufacturerTemplates = new List<Guid>();
        if (Manufacturers != null)
        {
            foreach (var manufacturer in Manufacturers)
            {
                if (manufacturer.Models != null)
                {
                    foreach (var model in manufacturer.Models)
                    {
                        if (model.Versions != null)
                        {
                            foreach (var version in model.Versions)
                            {
                                if (version.Settings != null)
                                {
                                    foreach (var settings in version.Settings)
                                    {
                                        if (settings.Template != null)
                                        {
                                            //If manufacturer template.
                                            manufacturerTemplates.Add(settings.Template.Id);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            ManufacturerTemplates = new List<GXDeviceTemplate>();
            CustomTemplates = new List<GXDeviceTemplate>();
            foreach (var it in templates)
            {
                if (manufacturerTemplates.Contains(it.Id))
                {
                    ManufacturerTemplates.Add(it);
                }
                else
                {
                    CustomTemplates.Add(it);
                }
            }
        }
    }

    protected override async Task OnInitializedAsync()
    {
        try
        {
            switch (Action)
            {
                case "Add":
                    Title = Properties.Resources.Add;
                    break;
                case "Edit":
                    Title = Properties.Resources.Edit;
                    break;
                case "Remove":
                    Title = Properties.Resources.Remove;
                    break;
                default:
                    ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
                    return;
            }
            Title += " " + Properties.Resources.Device;
            if (Notifier == null)
            {
                throw new ArgumentException(Properties.Resources.InvalidNotifier);
            }
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            if (string.Compare(Action, "Add", true) != 0)
            {
                //Get device data.
                var tmp = (await Http.GetAsJsonAsync<GetDeviceResponse>(string.Format("api/Device?id={0}", Id)));
                //Get serial number if it's used.
                if (tmp?.Item != null && tmp.Item.Objects == null)
                {
                    //Get serial number object.
                    ListObjects req2 = new ListObjects()
                        {
                            Select = new string[] { "Attribute" },
                            Filter = new GXObject()
                            {
                                Device = new GXDevice() { Id = tmp.Item.Id },
                                Template = new GXObjectTemplate()
                                {
                                    LogicalName = "0.0.42.0.0.255"
                                },
                            }
                        };
                    var tmp3 = (await Http.PostAsJson<ListObjectsResponse>("api/Object/List", req2));
                    if (tmp3.Objects != null && tmp3.Objects.Length == 1)
                    {
                        tmp.Item.Objects = new List<GXObject>(tmp3.Objects);
                    }
                }

                if (tmp?.Item != null)
                {
                    Active = tmp.Item;
                    StateHasChanged();
                }
                else
                {
                    NavigationManager.NavigateTo("404");
                }
            }
            //Get installed manufacturer settings.
            var filter2 = new Gurux.DLMS.AMI.Shared.DTOs.Manufacturer.GXManufacturer(null);
            filter2.Template = true;
            GXDeviceModel model = new GXDeviceModel(null);
            GXDeviceVersion version = new GXDeviceVersion(null);
            GXDeviceSettings settings = new GXDeviceSettings();
            settings.InstallationTime = DateTimeOffset.MinValue;
            if (Action != "Add")
            {
                //Get only selected manufacturer.
                settings.Template = Active.Template;
            }
            filter2.Models.Add(model);
            model.Versions.Add(version);
            version.Settings.Add(settings);
            ListManufacturersResponse ret2 = await Http.PostAsJson<ListManufacturersResponse>("api/Manufacturer/List",
            new ListManufacturers()
                {
                    Filter = filter2,
                    //Get model and version info.
                    Select = new string[] { "Version" }
                });
            List<GXManufacturer> tmp2 = new List<GXManufacturer>(ret2.Manufacturers);
            //Add custom manufacturer.
            tmp2.Add(new GXManufacturer(Properties.Resources.Custom));
            Manufacturers = tmp2.ToArray();

            //Get device templates.
            ListDeviceTemplates req = new ListDeviceTemplates()
                {
                    Filter = new GXDeviceTemplate()
                };
            if (Active?.Template != null && Action != "Add")
            {
                //Get only selected template.
                var ret = await Http.GetAsJsonAsync<GetDeviceTemplateResponse>("api/DeviceTemplate?Id=" + Active.Template.Id);
                UpdateTemplates(new GXDeviceTemplate[] { ret.Item });
            }
            else
            {
                //Get all templates when new device is added.
                var ret = await Http.PostAsJson<ListDeviceTemplatesResponse>("api/DeviceTemplate/List", req);
                UpdateTemplates(ret.Templates);
            }
            //Check are manufacturers empty.
            bool empty = true;
            foreach (var manufacturer in Manufacturers)
            {
                if (manufacturer.Models != null)
                {
                    foreach (var model2 in manufacturer.Models)
                    {
                        if (model2.Versions != null)
                        {
                            foreach (var version2 in model2.Versions)
                            {
                                empty = version2.Settings == null || !version2.Settings.Any();
                                if (!empty)
                                {
                                    break;
                                }
                            }
                            if (!empty)
                            {
                                break;
                            }
                        }
                    }
                    if (!empty)
                    {
                        break;
                    }
                }
            }
            if (empty && (Templates == null || !Templates.Any()))
            {
                NotInitialized = true;
                //Ask user to install manufacturers or device templates if they are not installed yet.
                Notifier.ShowInformation(string.Format(Properties.Resources.DeviceTemplatesNotInstalled, "<a href=/config/Manufacturer>", "</a>", "<a href=/DeviceTemplate>", "</a>"));
            }
            _device?.Update();
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }
}

